﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.OleDb;
using System.IO;
using System.Net;
using System.Xml;

/// <summary>
/// UpdateRssNews 的摘要说明
/// </summary>
public class UpdateRssNews
{
	public UpdateRssNews()
	{		
		// TODO: 在此处添加构造函数逻辑
        this.connection = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
        //this.connection = //GetConfigContent.ConnectionStringNews;
        //    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
        //    HttpContext.Current.Server.MapPath("~/App_Data/rss.mdb");
	}
    private string connection;

    public void UpdateAllSiteNews()
    {
        int sid, showCount, timeSpan, errorN;
        string url, tempId;
        DateTime expiryTime;

        string command = "select top 1 SiteId, Url, NewsCount, ExpiryTime, TimeSpan, ErrorN,newsPageTempId from Sites where IsLatest=true order by ExpiryTime";
        OleDbConnection cnn = new OleDbConnection(connection);
        OleDbCommand cmd = new OleDbCommand(command, cnn);
        cnn.Open();
        OleDbDataReader reader = cmd.ExecuteReader();
        if (reader.Read())
        {
            sid = int.Parse(reader[0].ToString()); url = reader.GetString(1); showCount = int.Parse(reader[2].ToString());
            expiryTime = reader.GetDateTime(3); timeSpan = int.Parse(reader[4].ToString()); errorN = int.Parse(reader[5].ToString());
            tempId = reader[6].ToString();
            reader.Close();
            cnn.Close();
        }
        else //not data, that means the param "k" is invalid
        {
            reader.Close();
            cnn.Close();
            return;
        }

        try
        {
            if (expiryTime <= DateTime.Now)
            {
                DownloadXml(sid, url, showCount, timeSpan, tempId);//, connection
            }
        }
        catch (Exception xmlDownEx)
        {
            string error = xmlDownEx.Message;
            error = error.Replace('\'', ' ');
            string errorCommand = "insert into errors(SiteId,Description,ErrorTime,Url) values(" + sid.ToString() + ",'" + error + "','" + DateTime.Now.ToString() + "','" + url + "')";
            cmd.CommandText = errorCommand;
            cnn.Open();
            cmd.ExecuteNonQuery();
            cnn.Close();
            UpdateExpiryTime(sid, timeSpan * 2);////下载或插入出错时，更新时间，加2小时。 , connection
        }
    }
    /// <summary>
    /// 手动更新单个站点的新闻
    /// </summary>
    /// <param name="sid">站点ID</param>
    /// <param name="url">站点地址</param>
    /// <param name="showCount">显示新闻的条数</param>
    /// <param name="timeSpanMinute">增加的时间间隔</param>
    /// <returns>返回值，正常为ok出错为异常原因</returns>
    public string UpdateOneSite(int sid, string url, int showCount, int timeSpanMinute)
    {
        string result = "ok";
        try
        {
            DownloadXml(sid, url, showCount, timeSpanMinute, "无");
        }
        catch (Exception e)
        { result = e.Message; }
        return result;
    }
    protected void DownloadXml(int sid, string url, int showCount, int timeSpan, string templateId)//, string connection
    {
        string haveDetail = templateId == "无" ? "3" : "0";
        byte[] rssXml = new WebClient().DownloadData(url);
        XmlDocument doc = new XmlDocument();
        doc.Load(new MemoryStream(rssXml));
        XmlNodeList items = doc.SelectNodes("rss/channel/item");
        string title, link, pubDate;
        int sameCount = 0, insertCount = showCount;
        int maxNumber = GetMaxInsertNumber();//取得RssNews中最大的InsertNumber值，即最后插入的值connection
        foreach (XmlNode item in items)
        {
            link = item.SelectSingleNode("link").InnerText;
            string haveCmd = "SELECT count(link) AS linkCount FROM RssNews WHERE siteId=" + sid.ToString() + " and link='" + link + "'";
            OleDbConnection cnnhave = new OleDbConnection(connection);
            OleDbCommand cmdhave = new OleDbCommand(haveCmd, cnnhave);
            cnnhave.Open();
            int counter = (int)cmdhave.ExecuteScalar();
            cnnhave.Close();
            if (counter > 0)
            {
                if (++sameCount > 3) //如果连续三个都已经有，跳出循环，更新站点时间。
                    break;
                else
                    continue;
            }
            else
            {
                title = item.SelectSingleNode("title").InnerText;
                pubDate = ParsePubDate(item.SelectSingleNode("pubDate").InnerText);
                int num = (maxNumber + insertCount--);
                sameCount = 0;//有新的，将 sameCount 重置为零

                OleDbConnection cnn = new OleDbConnection(connection);
                OleDbCommand com = new OleDbCommand("insert into RssNews(title,link,pubDate,siteId,insertNumber,haveNewsDetail) values('"
                    + title + "','" + link + "','" + pubDate + "','" + sid + "'," + num.ToString() + "," + haveDetail + ")", cnn);
                try
                {
                    cnn.Open();
                    com.ExecuteNonQuery();
                }
                catch (Exception exx)
                {
                    insertCount++;
                }
                finally
                {
                    cnn.Close();
                }
                if (insertCount == 0)//加够 showCount 条后，跳出。
                { break; }
            }
        }//end foreach

        int RssNewsCount = GetRssNewsCount(sid); //get news number, where news is not ad  (adNumber = 2), connection
        while (RssNewsCount > showCount)
        {
            try
            {
                DeleteTop(sid);  //delete top one news,which is not ad , connection
            }
            catch (Exception deleteEx)
            {
                string error = deleteEx.Message;
                error = error.Replace('\'', ' ');
                string errorCommand = "insert into errors(SiteId,Description,ErrorTime,Url) values(" + sid.ToString() + ",'我的程序删除数据出错，原因：" + error + "','" + DateTime.Now.ToString() + "','" + url + "')";
                OleDbConnection cnnInsert = new OleDbConnection(connection);
                OleDbCommand cmdInsert = new OleDbCommand(errorCommand, cnnInsert);//
                cmdInsert.CommandText = errorCommand;
                cnnInsert.Open();
                cmdInsert.ExecuteNonQuery();
                cnnInsert.Close();                
            }
            RssNewsCount--;
        
        }
        UpdateExpiryTime(sid, timeSpan);//, connection
    }
    /// <summary>
    /// 将RSS源的日期处理成某月某日
    /// </summary>
    /// <param name="pubDate">RSS的日期</param>
    /// <returns>月日</returns>
    protected string ParsePubDate(string pubDate)
    {
        string result;
        try
        {
            DateTime date = DateTime.Parse(pubDate);
            string hour,minute;
            hour = (date.Hour < 10) ? "0" + date.Hour.ToString() : date.Hour.ToString();
            minute = (date.Minute < 10) ? "0" + date.Minute.ToString() : date.Minute.ToString();
            result = date.Month.ToString() + "月" + date.Day.ToString() + "日" + hour + ":" + minute;
        }
        catch (Exception ex)
        {
            result = DateTime.Now.Month.ToString() + "月" + DateTime.Now.Day.ToString() + "日";
        }
        return result;
    }    
    protected void DeleteTop(int sid)//, string connection
    {
        OleDbConnection cnn = new OleDbConnection(connection);
        OleDbCommand cmd = new OleDbCommand("DeleteMin", cnn);//
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("siteId", OleDbType.Integer, 4).Value = sid;
        cnn.Open();
        cmd.ExecuteScalar();
        cnn.Close();
    }
    protected int GetRssNewsCount(int sid)//, string connection
    {
        OleDbConnection cnn = new OleDbConnection(connection);
        OleDbCommand cmd = new OleDbCommand("GetRssNewsCount", cnn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("siteId", OleDbType.Integer, 4).Value = sid;

        cnn.Open();
        int number = (int)cmd.ExecuteScalar();
        cnn.Close();
        return number;
    }
    protected int GetMaxInsertNumber()//string connection
    {
        OleDbConnection cnn = new OleDbConnection(connection);
        OleDbCommand cmd = new OleDbCommand("GetMaxInsertNumber", cnn);
        cmd.CommandType = CommandType.StoredProcedure;
        cnn.Open();
        int number = (int)cmd.ExecuteScalar();
        cnn.Close();
        return number;
    }

    protected void UpdateExpiryTime(int sid, int timeSpan)//, string connection
    {
        OleDbConnection cnn = new OleDbConnection(connection);
        string command = "update Sites set ExpiryTime='" + DateTime.Now.AddMinutes(timeSpan) + "' where SiteId=" + sid.ToString();
        OleDbCommand cmd = new OleDbCommand(command, cnn);
        cnn.Open();
        int count = cmd.ExecuteNonQuery();
        cnn.Close();
    }
}
